{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 条形图 (Bar Chart) 教程\n",
    "\n",
    "本部分将详细讲解如何使用 Matplotlib 绘制条形图，包括垂直条形图、水平条形图、分组条形图和堆叠条形图。\n",
    "\n",
    "## 学习内容\n",
    "1. **垂直条形图**\n",
    "   -  绘制垂直条形图\n",
    "   - ：柱子宽度\n",
    "   - ：柱子颜色（单个或列表）\n",
    "   - ：边框颜色\n",
    "   - ：对齐方式（, ）\n",
    "\n",
    "2. **水平条形图**\n",
    "   -  绘制水平条形图\n",
    "   - 使用场景：类别名称较长时\n",
    "\n",
    "3. **分组条形图**\n",
    "   - 多组数据并排显示\n",
    "   - 使用  位置偏移实现分组\n",
    "\n",
    "4. **堆叠条形图**\n",
    "   -  参数：堆叠多个条形图\n",
    "   - 使用场景：显示部分与整体的关系"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入必要的库\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "# 设置中文字体（如果需要显示中文）\n",
    "plt.rcParams['font.sans-serif'] = ['PingFang SC', 'Arial Unicode MS']\n",
    "plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题\n",
    "\n",
    "# 在 Jupyter Notebook 中内联显示图形\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第一部分：垂直条形图\n",
    "\n",
    "垂直条形图是最常用的条形图类型，用于比较不同类别的数值大小。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.1 plt.bar(x, height) 绘制垂直条形图\n",
    "\n",
    "`plt.bar(x, height)` 是绘制垂直条形图的基础函数。\n",
    "\n",
    "**基本语法**：\n",
    "```python\n",
    "plt.bar(x, height)\n",
    "```\n",
    "\n",
    "**参数说明**：\n",
    "- `x`：柱子的 x 轴位置（可以是数值或类别标签的位置）\n",
    "- `height`：柱子的高度（数值）\n",
    "- `width`：柱子的宽度（默认 0.8）\n",
    "- `color`：柱子的颜色（单个颜色或颜色列表）\n",
    "- `edgecolor`：边框颜色\n",
    "- `align`：对齐方式（`'center'` 默认，`'edge'`）\n",
    "\n",
    "**返回值**：\n",
    "- 返回一个 `BarContainer` 对象，包含所有柱子对象\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 示例 1：基础垂直条形图\n",
    "categories = ['产品A', '产品B', '产品C', '产品D', '产品E']\n",
    "values = [23, 45, 56, 78, 32]\n",
    "\n",
    "plt.figure(figsize=(10, 6))\n",
    "plt.bar(categories, values)\n",
    "plt.title('基础垂直条形图示例', fontsize=14)\n",
    "plt.xlabel('产品类别', fontsize=12)\n",
    "plt.ylabel('销售额（万元）', fontsize=12)\n",
    "plt.grid(True, alpha=0.3, axis='y')\n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2 柱子宽度、颜色和边框\n",
    "\n",
    "条形图支持丰富的定制选项，包括宽度、颜色和边框。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 示例 2：定制条形图\n",
    "categories = ['产品A', '产品B', '产品C', '产品D', '产品E']\n",
    "values = [23, 45, 56, 78, 32]\n",
    "colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8']\n",
    "\n",
    "fig, axes = plt.subplots(1, 3, figsize=(15, 5))\n",
    "\n",
    "# 不同宽度\n",
    "axes[0].bar(categories, values, width=0.5, color='steelblue')\n",
    "axes[0].set_title('窄柱子 (width=0.5)', fontsize=12)\n",
    "axes[0].set_ylabel('销售额（万元）', fontsize=10)\n",
    "axes[0].grid(True, alpha=0.3, axis='y')\n",
    "\n",
    "# 不同颜色\n",
    "axes[1].bar(categories, values, color=colors)\n",
    "axes[1].set_title('不同颜色', fontsize=12)\n",
    "axes[1].set_ylabel('销售额（万元）', fontsize=10)\n",
    "axes[1].grid(True, alpha=0.3, axis='y')\n",
    "\n",
    "# 边框\n",
    "axes[2].bar(categories, values, color='steelblue', edgecolor='black', linewidth=2)\n",
    "axes[2].set_title('带边框', fontsize=12)\n",
    "axes[2].set_ylabel('销售额（万元）', fontsize=10)\n",
    "axes[2].grid(True, alpha=0.3, axis='y')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第二部分：水平条形图\n",
    "\n",
    "水平条形图使用 `plt.barh()` 函数绘制，适合类别名称较长的情况。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1 plt.barh(y, width) 绘制水平条形图\n",
    "\n",
    "`plt.barh(y, width)` 是绘制水平条形图的基础函数。\n",
    "\n",
    "**基本语法**：\n",
    "```python\n",
    "plt.barh(y, width)\n",
    "```\n",
    "\n",
    "**参数说明**：\n",
    "- `y`：柱子的 y 轴位置\n",
    "- `width`：柱子的宽度（数值，对应垂直条形图的 height）\n",
    "- `height`：柱子的高度（默认 0.8，对应垂直条形图的 width）\n",
    "- 其他参数与 `plt.bar()` 相同\n",
    "\n",
    "**使用场景**：\n",
    "- 类别名称较长时，水平条形图更容易阅读\n",
    "- 需要展示排名或排序数据时\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 示例 3：水平条形图\n",
    "categories = ['产品A - 高端系列', '产品B - 中端系列', '产品C - 入门系列', \n",
    "              '产品D - 专业系列', '产品E - 旗舰系列']\n",
    "values = [23, 45, 56, 78, 32]\n",
    "\n",
    "plt.figure(figsize=(10, 6))\n",
    "plt.barh(categories, values, color='steelblue', edgecolor='black')\n",
    "plt.title('水平条形图示例', fontsize=14)\n",
    "plt.xlabel('销售额（万元）', fontsize=12)\n",
    "plt.ylabel('产品类别', fontsize=12)\n",
    "plt.grid(True, alpha=0.3, axis='x')\n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第三部分：分组条形图\n",
    "\n",
    "分组条形图用于比较多个组别的数据，通过并排显示不同组别的柱子来实现。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.1 使用 x 位置偏移实现分组\n",
    "\n",
    "分组条形图的核心思想是通过调整 x 轴位置，让不同组别的柱子并排显示。\n",
    "\n",
    "**实现步骤**：\n",
    "1. 定义类别位置（x 轴）\n",
    "2. 计算每组柱子的偏移位置\n",
    "3. 分别绘制每组数据\n",
    "4. 添加图例\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 示例 4：分组条形图\n",
    "categories = ['产品A', '产品B', '产品C', '产品D', '产品E']\n",
    "x = np.arange(len(categories))\n",
    "width = 0.35  # 柱子宽度\n",
    "\n",
    "# 两组数据\n",
    "values1 = [23, 45, 56, 78, 32]  # 第一季度\n",
    "values2 = [28, 50, 62, 85, 38]  # 第二季度\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(12, 6))\n",
    "\n",
    "# 绘制两组数据，通过 x 位置偏移实现分组\n",
    "bars1 = ax.bar(x - width/2, values1, width, label='第一季度', color='steelblue', edgecolor='black')\n",
    "bars2 = ax.bar(x + width/2, values2, width, label='第二季度', color='coral', edgecolor='black')\n",
    "\n",
    "ax.set_xlabel('产品类别', fontsize=12)\n",
    "ax.set_ylabel('销售额（万元）', fontsize=12)\n",
    "ax.set_title('分组条形图：两个季度销售额对比', fontsize=14)\n",
    "ax.set_xticks(x)\n",
    "ax.set_xticklabels(categories)\n",
    "ax.legend(fontsize=11)\n",
    "ax.grid(True, alpha=0.3, axis='y')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第四部分：堆叠条形图\n",
    "\n",
    "堆叠条形图用于显示部分与整体的关系，通过将多个数据系列堆叠在一起实现。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1 使用 bottom 参数实现堆叠\n",
    "\n",
    "堆叠条形图的核心是使用 `bottom` 参数，将后续的柱子堆叠在前面的柱子上。\n",
    "\n",
    "**基本语法**：\n",
    "```python\n",
    "plt.bar(x, values1, label='组1')\n",
    "plt.bar(x, values2, bottom=values1, label='组2')  # 堆叠在 values1 上\n",
    "plt.bar(x, values3, bottom=values1+values2, label='组3')  # 堆叠在前两组上\n",
    "```\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 示例 5：堆叠条形图\n",
    "categories = ['产品A', '产品B', '产品C', '产品D', '产品E']\n",
    "x = np.arange(len(categories))\n",
    "\n",
    "# 三组数据（各部分）\n",
    "values1 = [10, 15, 20, 25, 12]  # 线上销售\n",
    "values2 = [8, 20, 25, 35, 15]   # 线下销售\n",
    "values3 = [5, 10, 11, 18, 5]    # 其他渠道\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(12, 6))\n",
    "\n",
    "# 绘制堆叠条形图\n",
    "bars1 = ax.bar(x, values1, label='线上销售', color='#FF6B6B', edgecolor='black')\n",
    "bars2 = ax.bar(x, values2, bottom=values1, label='线下销售', color='#4ECDC4', edgecolor='black')\n",
    "bars3 = ax.bar(x, values3, bottom=np.array(values1) + np.array(values2), \n",
    "                label='其他渠道', color='#45B7D1', edgecolor='black')\n",
    "\n",
    "ax.set_xlabel('产品类别', fontsize=12)\n",
    "ax.set_ylabel('销售额（万元）', fontsize=12)\n",
    "ax.set_title('堆叠条形图：不同销售渠道的销售额', fontsize=14)\n",
    "ax.set_xticks(x)\n",
    "ax.set_xticklabels(categories)\n",
    "ax.legend(fontsize=11)\n",
    "ax.grid(True, alpha=0.3, axis='y')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结\n",
    "\n",
    "本教程详细介绍了 Matplotlib 条形图的绘制方法，包括：\n",
    "\n",
    "1. **垂直条形图**：使用 `plt.bar(x, height)` 绘制，支持宽度、颜色、边框、对齐等定制\n",
    "2. **水平条形图**：使用 `plt.barh(y, width)` 绘制，适合类别名称较长的情况\n",
    "3. **分组条形图**：通过 x 位置偏移实现多组数据并排显示\n",
    "4. **堆叠条形图**：使用 `bottom` 参数实现多组数据堆叠，显示部分与整体的关系\n",
    "\n",
    "**关键要点**：\n",
    "- 条形图适合比较不同类别的数值大小\n",
    "- 水平条形图在类别名称较长时更易读\n",
    "- 分组条形图适合比较多个组别的数据\n",
    "- 堆叠条形图适合展示部分与整体的关系\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.8.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
